mat1 = {{0, 0, 1, 1}, {0, 1, 0, 1}};
Using Table and GatherBy:
Flatten /@ GatherBy[Catenate@Table[mat1, {4}]]
({{0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1},
{0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}})
Using GatherBy to address this problem is possible as long as the matrix doesn't have all its elements equal, but we can generalize this strategy using Partition as shown below:
repeatMat[mat_?MatrixQ, n_Integer?Positive] := Module[{repmat},
repmat = Catenate @ Table[mat, {n}];
If[MatchQ[Flatten @ repmat, {Repeated[m_Integer]}],
Map[Flatten, Partition[repmat, n]],
Map[Flatten, GatherBy @ repmat]
]
];
mat2 = {{1, 1}, {1, 1}};
repeatMat[mat1, 4] === Join[mat1, mat1, mat1, mat1, 2]
(True)
repeatMat[mat2, 4] === Join[mat2, mat2, mat2, mat2, 2]
(True)